package biolabs.query;

import java.math.BigDecimal;

import biolabs.core.BioObject;

/**
 * Predicate that compares the results of two expressions for equality.
 * The results are considered equal if both are non-<tt>null</tt> and
 * <ul>
 *  <li>both are numeric values (one of Long, Integer, Short, Byte, Double,
 *  Float, BigInteger, BigDecimal, AtomicInteger, AtomicLong) and represent
 *  the same numeric value; or</li>
 *  <li>they are equal by means of the {@code equals(Object)} method
 *  of the first one.</li>
 * </ul>
 *
 * @author Tomas Mikula
 */
public class Equal implements Predicate {

	private final Expression a;
	private final Expression b;

	public Equal(Expression a, Expression b) {
		if(a == null || b == null)
			throw new NullPointerException();
		this.a = a;
		this.b = b;
	}

	@Override
	public boolean eval(BioObject obj) {
		Object valA = a.eval(obj);
		Object valB = b.eval(obj);

		if(valA == null || valB == null)
			return false;

		BigDecimal bigA = NumericPredicate.toBigDecimal(valA);
		BigDecimal bigB = NumericPredicate.toBigDecimal(valB);
		if(bigA != null && bigB != null)
			return bigA.compareTo(bigB) == 0;

		return valA.equals(valB);
	}

}
